package com.orm.analysis.util;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.PreResultListener;
import com.orm.analysis.action.FrontendAction;
import com.orm.analysis.dao.GenericJPADAO;
import com.orm.analysis.dao.impl.PerfAnalysisDAO;
import com.orm.analysis.model.Address;
import com.orm.analysis.model.PerfAnalysis;
import com.orm.analysis.service.GenericService;
import com.sun.xml.bind.v2.model.core.ID;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ProfilingActivationInterceptor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import com.opensymphony.xwork2.ActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.From;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: saman
 * Date: 10/17/13
 * Time: 10:39 AM
 * To change this template use File | Settings | File Templates.
 */

public class AppProfiler  extends AbstractInterceptor {

    @Autowired
    protected  GenericService<PerfAnalysis> perfAnalysisService;

    public GenericService<PerfAnalysis> getPerfAnalysisService() {
        return perfAnalysisService;
    }

    public void setPerfAnalysisService(GenericService<PerfAnalysis> perfAnalysisService) {
        this.perfAnalysisService = perfAnalysisService;
    }


	public String intercept(ActionInvocation invocation) throws Exception {

        String className = invocation.getAction().getClass().getName();
        long startTime = System.currentTimeMillis();
        System.out.println("Before calling action: " + className);


        Object action = invocation.getAction();
        if (action instanceof FrontendAction) {


           Map<String, Object> sessionMap = invocation.getInvocationContext().getContextMap();

            Map<String, String[]> parameters =( Map<String, String[]>) sessionMap.get("parameters");
//            parameters
//            while (iter.hasNext()){
//                System.out.println(" retrived session "+ iter.next()..toString() );
//            }


          //  System.out.println((( Map<String, String[]>) sessionMap.get("parameters")).get("criteria")[0]);
          //  System.out.println((( Map<String, String[]>) sessionMap.get("parameters")).get("criteriaSubId")[0]);

            //System.out.print(invocation.getInvocationContext().getSession().getAttribute("criteria"));
            //System.out.print(invocation.getInvocationContext().getSession().getAttribute("subcriteria"));

            String classNameVal = invocation.getProxy().getAction().toString();

            String criteria= null;
            if(parameters.get("criteria")!=null && parameters.get("criteria").length>0){
                criteria= parameters.get("criteria")[0];
            }
            String criteriaSubId=null;
            if(parameters.get("criteriaSubId")!=null &&  parameters.get("criteriaSubId").length>0){
                criteriaSubId= parameters.get("criteriaSubId")[0];
            }


            HttpServletRequest request  = ServletActionContext.getRequest();
            if(criteria==null){
                criteria=request.getParameter("criteria");
            }
            if(criteriaSubId==null){
                criteriaSubId=request.getParameter("criteriaSubId");
            }


            ((FrontendAction) action).setPerfAnalysis(
                    new PerfAnalysis(criteria ,
                            criteriaSubId,
                            classNameVal.subSequence(classNameVal.lastIndexOf('.')+1,classNameVal.indexOf('@')).toString().
                            replace("Action", ""),
                            invocation.getProxy().getMethod(),
                            GlobalConst.ormTool_H,
                            startTime,
                            1));
        }


        invocation.addPreResultListener(new PreResultListener() {
            public void beforeResult(ActionInvocation actionInvocation, String s) {
                Object action = actionInvocation.getAction();
                try {
                    Result result= actionInvocation.getResult();

                } catch (Exception e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
                if (action instanceof FrontendAction) {

                    PerfAnalysis perfAnalysis = ((FrontendAction) action).getPerfAnalysis();

                    long processingStartTime = perfAnalysis.getTimeToPerf();
                    long currentTime = Calendar.getInstance().getTimeInMillis();

                    perfAnalysis.setTimeToPerf(currentTime - processingStartTime);


                    perfAnalysisService.create(perfAnalysis);
                }


            }
        });


        return invocation.invoke();

    }

	public void destroy() {
		System.out.println("Destroying MyLoggingInterceptor...");
	}

	public void init() {
		System.out.println("Initializing MyLoggingInterceptor...");
	}

}
//
//
//    Logger log = Logger.getLogger(AppProfiler.class);
//
//    @Override
//    public String intercept(ActionInvocation actionInvocation) throws Exception {
//
//        System.out.println(">>>>>>>>>>>>>>>>>>>>");
//        return actionInvocation.invoke();
//    }
//    @Around("execution(* com.orm.analysis.dao.impl.*.*(..))")
//    public Object profileDAO(ProceedingJoinPoint _pjp) throws Throwable {
//        int mb = 1024 * 1024;
//        long start = System.currentTimeMillis();
//        //Getting the runtime reference from system
//        Runtime runtime = Runtime.getRuntime();
//        System.out.println("##### Heap utilization statistics [MB] #####");
//        //Print used memory
//        System.out.println("Used Memory:"
//                + (runtime.totalMemory() - runtime.freeMemory()) / mb);
//
//        //Print free memory
//        System.out.println("Free Memory:"
//                + runtime.freeMemory() / mb);
//
//        //Print total available memory
//        System.out.println("Total Memory:" + runtime.totalMemory() / mb);
//
//        //Print Maximum available memory
//        System.out.println("Max Memory:" + runtime.maxMemory() / mb);
//
//
//        Object output = _pjp.proceed();
//
//        long elapsedTime = System.currentTimeMillis() - start;
//        log.debug("dao Method: " + _pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " ms.");
//        System.out.println("dao Method: " + _pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " ms.");
//        //this.save( new PerfAnalysis(GlobalConst.ormTool_H,Double.longBitsToDouble(elapsedTime),GlobalConst.criteriaA, _pjp.getSignature().toShortString()));
//
//        return output;
//    }
//
//
//        @Around("execution(* com.orm.analysis.service.*.*(..))" )
//    public Object profileService(ProceedingJoinPoint _pjp) throws Throwable {
//        long start = System.currentTimeMillis();
//        Object output = _pjp.proceed();
//        long elapsedTime = System.currentTimeMillis() - start;
//        log.debug("service Method: " + _pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " ms.");
//        System.out.println("service Method: " + _pjp.getSignature().toShortString() + ", execution time: " + elapsedTime + " ms.");
//
//        return output;
//    }

//}
